package logic

import (
	"context"
	"strings"

	"mall/common/enumx"
	"mall/common/modelx"
	"mall/common/resultx"
	"mall/service/forum/model"
	"mall/service/forum/rpc/internal/svc"
	"mall/service/forum/rpc/types/forum"

	"github.com/zeromicro/go-zero/core/logx"
)

type NoticeListLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewNoticeListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NoticeListLogic {
	return &NoticeListLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *NoticeListLogic) NoticeList(in *forum.NoticeListReq) (*forum.NoticeListResp, error) {
	logx.Infof("NoticeListReq: %+v ", in)
	// 

	if in.Preload == "" && in.EagerLoad == "" {
		return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
	}

	preloadMap, eagerLoadMap := modelx.GetPreloadMap(in.Preload, in.EagerLoad)
	logx.Infof("preloadMap: %+v ", preloadMap)
	// preloadMap:
	logx.Infof("eagerLoadMap: %+v ", eagerLoadMap)
	// eagerLoadMap:

	forumNoticeEntityName := model.RpcEntityNames.ForumNotice
	_, hasSettingMap := model.RpcEntityPreloadMap[forumNoticeEntityName] // ForumNotice的关联字段
	if !hasSettingMap {
		return &forum.NoticeListResp{}, nil
	}

	forumNoticeRepositoryName := model.RepositoryNames.ForumNotice
	columnMap, hasColumnMap := model.RepositoryPreloadMap[forumNoticeRepositoryName] // ForumNotice的数据库字段
	if !hasColumnMap {
		return &forum.NoticeListResp{}, nil
	}

	// 解析 preload 的字段
	var selectCols []string
	if preloadFields, hasPreloadFields := preloadMap[forumNoticeEntityName]; hasPreloadFields {
		selectColMap := make(map[string]string)
		for _, field := range preloadFields {
			if _, exist := selectColMap[field]; !exist {
				if column, hasColumn := columnMap[field]; hasColumn {
					selectColMap[field] = column
				} else {
					selectColMap[field] = ""
				}
			}
		}
		for _, column := range selectColMap {
			if column != "" {
				selectCols = append(selectCols, column)
			}
		}
	}

	var count int64
	var err error
	var noticeList []*model.ForumUserNotice
	if in.NoticeIds != "" { // 根据ID获取
		filterMap := make(map[string]map[string][]interface{})
		filterMap[model.ForumUserNoticeColumns.NoticeID] = map[string][]interface{}{
			"in": modelx.UniqueValues(strings.Split(in.NoticeIds, ","), 64),
		}
		filterMap[model.ForumUserNoticeColumns.Status] = map[string][]interface{}{
			"notEqualTo": []interface{}{enumx.ObjectStatusDeleted},
		}

		noticeList, _, err = l.svcCtx.ForumUser.GetNotices(l.ctx, model.M{
			"orderBy": model.ForumUserNoticeColumns.NoticeID + " DESC",
		}, -1, filterMap)
		if err != nil {
			return nil, err
		}
	} else if in.VisitorId > 0 {
		filterMap := make(map[string]map[string][]interface{})
		filterMap[model.ForumUserNoticeColumns.UserID] = map[string][]interface{}{
			"equalTo": []interface{}{in.VisitorId},
		}
		filterMap[model.ForumUserNoticeColumns.Status] = map[string][]interface{}{
			"notEqualTo": []interface{}{enumx.ObjectStatusDeleted},
		}
		noticeList, count, err = l.svcCtx.ForumUser.GetNotices(l.ctx, model.M{
			"offset":  in.Offset,
			"limit":   in.Limit,
			"orderBy": model.ForumUserNoticeColumns.NoticeID + " DESC",
		}, 2, filterMap)
		if err != nil {
			return nil, err
		}
	}

	var notices []*forum.NoticeDetailResp
	if len(noticeList) > 0 {
		for _, notice := range noticeList {
			var sourceType string
			switch int64(notice.ForumID) {
			case l.svcCtx.Config.Query.PhotoForumId:
				sourceType = "photo"
			case l.svcCtx.Config.Query.PostForumId:
				sourceType = "review"
			default:
				if int64(notice.ForumID) >= l.svcCtx.Config.Query.DefaultForumId {
					if notice.PostID > 0 {
						sourceType = "answer"
					} else {
						sourceType = "question"
					}
				}
			}
			notices = append(notices, &forum.NoticeDetailResp{
				Id:         int64(notice.NoticeID),
				UserId:     int64(notice.UserID),
				ForumId:    int64(notice.ForumID),
				ParentId:   int64(notice.ParentID),
				TopicId:    int64(notice.TopicID),
				PostId:     int64(notice.PostID),
				CommentId:  int64(notice.CommentID),
				Type:       int32(notice.Type),
				Avatar:     notice.Avatar,
				Title:      notice.Title,
				Desc:       notice.Description,
				Extra:      notice.Extra,
				Status:     int32(notice.Status),
				ReadAt:     modelx.FormatNullDotTime(notice.ReadAt, ""),
				CreatedAt:  modelx.FormatTime(notice.CreatedAt, ""),
				UpdatedAt:  modelx.FormatTime(notice.UpdatedAt, ""),
				SourceType: sourceType,
			})
		}
	}

	var hasNextPage int32
	var hasPreviousPage int32
	if count > 1 {
		hasNextPage = 1
		count = count - 2
	}
	if count > 0 {
		hasPreviousPage = 1
	}
	return &forum.NoticeListResp{
		Data: notices,
		HasNextPage: hasNextPage,
		HasPreviousPage: hasPreviousPage,
	}, nil
}
